const http = require('http');
const httpProxy = require('http-proxy');
const path = require('path');
const fs = require('fs');
const url = require('url');

// 创建一个代理服务器
const proxy = httpProxy.createProxyServer({
  // 添加超时设置
  proxyTimeout: 5000,
  timeout: 5000
});

// 错误处理
proxy.on('error', (err, req, res) => {
  console.error('代理错误:', err.message);
  
  // 检查目标服务是否可用
  const targetUrl = req.targetUrl || '未知目标';
  console.error(`无法连接到目标服务: ${targetUrl}`);
  
  if (!res.headersSent) {
    res.writeHead(502, { 'Content-Type': 'text/plain; charset=utf-8' });
    res.end(`代理服务器错误: 无法连接到目标服务 ${targetUrl}\n\n${err.message}`);
  }
});

// 添加代理事件监听
proxy.on('proxyReq', (proxyReq, req, res, options) => {
  console.log(`发送代理请求: ${req.method} ${req.url} -> ${options.target.href}`);
});

proxy.on('proxyRes', (proxyRes, req, res) => {
  console.log(`收到代理响应: ${proxyRes.statusCode} ${proxyRes.statusMessage} <- ${req.targetUrl}`);
});

// 创建路由映射表
const routes = [
  {
    path: '/cloudyso',
    target: 'http://localhost:8081',
    type: 'proxy',
    description: '将 /cloudyso 路径代理到 http://localhost:8081/cloudyso'
  },
  {
    path: '/clue',
    target: 'http://localhost:8091',
    type: 'proxy',
    description: '将 /clue 路径代理到 http://localhost:8091/clue'
  },
  {
    path: '/',
    target: 'http://localhost:3000',
    type: 'proxy',
    description: '将 / 路径路径代理到 http://localhost:3000 '
  },
  {
    path: '/files',
    target: path.join(__dirname, 'files'),
    type: 'static',
    description: '将 /files 路径映射到本地 files 文件夹'
  },

];

// MIME类型映射
const mimeTypes = {
  '.html': 'text/html',
  '.js': 'text/javascript',
  '.css': 'text/css',
  '.json': 'application/json',
  '.png': 'image/png',
  '.jpg': 'image/jpg',
  '.gif': 'image/gif',
  '.svg': 'image/svg+xml',
  '.wav': 'audio/wav',
  '.mp3': 'audio/mpeg',
  '.mp4': 'video/mp4',
  '.woff': 'application/font-woff',
  '.ttf': 'application/font-ttf',
  '.eot': 'application/vnd.ms-fontobject',
  '.otf': 'application/font-otf',
  '.wasm': 'application/wasm',
  '.txt': 'text/plain'
};

// 提供静态文件服务
function serveStaticFile(req, res, filePath) {
  const reqPath = req.url.split('?')[0];
  
  // 构建完整的文件路径
  let fullPath = path.join(__dirname, reqPath);
  
  // 如果请求是目录，则尝试提供index.html
  fs.stat(fullPath, (err, stats) => {
    if (err) {
      console.error(`文件不存在: ${fullPath}`);
      res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
      res.end('404 未找到文件');
      return;
    }
    
    if (stats.isDirectory()) {
      fullPath = path.join(fullPath, 'index.html');
      fs.access(fullPath, fs.constants.F_OK, (err) => {
        if (err) {
          // 如果没有index.html，则显示目录列表
          fs.readdir(fullPath.replace('/index.html', ''), (err, files) => {
            if (err) {
              res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
              res.end('无法读取目录');
              return;
            }
            
            res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
            res.write(`<h1>目录: ${reqPath}</h1><ul>`);
            
            // 添加返回上级目录的链接
            if (reqPath !== '/') {
              const parentDir = path.dirname(reqPath);
              res.write(`<li><a href="${parentDir}">../</a></li>`);
            }
            
            files.forEach(file => {
              const filePath = path.join(reqPath, file);
              res.write(`<li><a href="${filePath}">${file}</a></li>`);
            });
            
            res.end('</ul>');
          });
          return;
        }
        
        // 提供index.html
        serveFile(fullPath, res);
      });
      return;
    }
    
    // 提供文件
    serveFile(fullPath, res);
  });
}

// 提供单个文件
function serveFile(filePath, res) {
  const extname = path.extname(filePath);
  const contentType = mimeTypes[extname] || 'application/octet-stream';
  
  fs.readFile(filePath, (err, content) => {
    if (err) {
      if (err.code === 'ENOENT') {
        console.error(`文件不存在: ${filePath}`);
        res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
        res.end('404 未找到文件');
      } else {
        console.error(`读取文件错误: ${filePath}`, err);
        res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
        res.end('500 服务器错误');
      }
      return;
    }
    
    console.log(`提供文件: ${filePath} (${contentType})`);
    res.writeHead(200, { 'Content-Type': contentType });
    res.end(content);
  });
}

// 创建HTTP服务器
const server = http.createServer((req, res) => {
  const parsedUrl = url.parse(req.url, true);
  const pathname = parsedUrl.pathname;
  
  console.log(`收到请求: ${req.method} ${pathname}`);
  
  // 检查是否匹配任何路由规则
  for (const route of routes) {
    if (pathname.startsWith(route.path)) {
      
      // 处理代理请求
      if (route.type === 'proxy') {
        const targetUrl = `${route.target}${pathname}`;
        console.log(`代理请求: ${pathname} -> ${targetUrl}`);
        
        // 保存目标URL用于错误处理
        req.targetUrl = targetUrl;
        
        // 尝试连接目标服务
        const testReq = http.request(targetUrl, {
          method: 'HEAD',
          timeout: 1000
        });
        
        testReq.on('response', () => {
          // 目标服务可用，执行代理
          proxy.web(req, res, {
            target: route.target,
            changeOrigin: true
          });
        });
        
        testReq.on('error', (err) => {
          console.error(`目标服务不可用: ${targetUrl}`);
          console.error(`错误: ${err.message}`);
          res.writeHead(502, { 'Content-Type': 'text/plain; charset=utf-8' });
          res.end(`错误: 目标服务 ${route.target} 不可用。\n\n请确保目标服务正在运行。`);
        });
        
        testReq.on('timeout', () => {
          console.error(`目标服务超时: ${targetUrl}`);
          testReq.destroy();
        });
        
        testReq.end();
        return;
      }
      const relativePath = pathname.replace(route.path, '');
      const filePath = path.join(route.target, relativePath);
      console.log(`静态文件请求: ${pathname} -> ${filePath}`);
      serveStaticFile(req, res, route.target);
      return;
    }
  }
  
  // 如果没有匹配的路由，返回404
  res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
  res.end('未找到匹配的路由');
});

// 设置代理服务器端口
const PORT = 3001;

// 启动服务器
server.listen(PORT, () => {
  console.log('===========================================');
  console.log(`代理服务器运行在 http://localhost:${PORT}`);
  console.log('===========================================');
  console.log('允许的路由:');
  routes.forEach(route => {
    if (route.type === 'proxy') {
      console.log(`- http://localhost:${PORT}${route.path}/... -> ${route.target}${route.path}/...`);
    } else if (route.type === 'static') {
      console.log(`- http://localhost:${PORT}${route.path}/... -> 本地文件夹: ${route.target}`);
    }
    console.log(`  ${route.description}`);
  });
  console.log('===========================================');
  console.log('使用 Ctrl+C 停止服务器');
  console.log('===========================================');
});
